﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections.Concurrent;
using System.Net.Http;
using System.Text.RegularExpressions;

namespace test7_g1
{
    public partial class Form1 : Form
    {
        private readonly HttpClient _httpClient;
        private readonly ConcurrentDictionary<string, HashSet<string>> _phoneNumbers;
        private readonly ConcurrentBag<string> _visitedUrls;
        private int _targetCount = 100;
        private bool _isCrawling = false;

        public Form1()
        {
            InitializeComponent();
            _httpClient = new HttpClient();
           // _httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0");
            _phoneNumbers = new ConcurrentDictionary<string, HashSet<string>>();
            _visitedUrls = new ConcurrentBag<string>();
            _httpClient.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");

            // 初始化ListView列
            lstResults.View = View.Details;
            lstResults.Columns.Add("电话号码", 150);
            lstResults.Columns.Add("来源URL", 300);

            lstUrls.View = View.List;
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void textBox1_TextChanged(object sender, EventArgs e)
        {

        }

        private void lblStatus_Click(object sender, EventArgs e)
        {

        }

        private void txtLog_TextChanged(object sender, EventArgs e)
        {

        }

        private async void btnSearch_Click(object sender, EventArgs e)
        {
            if (_isCrawling)
            {
                MessageBox.Show("爬取正在进行中，请稍候...");
                return;
            }

            string keyword = txtKeyword.Text.Trim();
            if (string.IsNullOrEmpty(keyword))
            {
                MessageBox.Show("请输入搜索关键字");
                return;
            }

            _isCrawling = true;
            btnSearch.Enabled = false;
            _phoneNumbers.Clear();
            while (!_visitedUrls.IsEmpty)
            {
                _visitedUrls.TryTake(out _);
            }
            lstResults.Items.Clear();
            lstUrls.Items.Clear();
            lblStatus.Text = "正在爬取...";

            try
            {
                await StartCrawling(keyword);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发生错误: {ex.Message}");
            }
            finally
            {
                _isCrawling = false;
                btnSearch.Enabled = true;
                
            }
        }

        private async Task StartCrawling(string keyword)
        {
            // 使用Bing搜索
            string searchUrl = $"https://www.baidu.com/s?wd={Uri.EscapeDataString(keyword + " 联系方式")}";

            try
            {
                string html = await _httpClient.GetStringAsync(searchUrl);
                var urls = ExtractUrlsFromSearchResults(html);

                // 并行处理搜索结果
                var options = new ParallelOptions { MaxDegreeOfParallelism = 5 };
                await Task.Run(() => Parallel.ForEach(urls.Take(50), options, async url =>
                {
                    if (_phoneNumbers.Count >= _targetCount) return;

                    try
                    {
                        await Task.Delay(new Random().Next(1000, 3000)); // 随机延迟1-3秒
                        await ProcessUrl(url);
                    }
                    catch (Exception ex)
                    {
                        Log($"处理URL {url} 时出错: {ex.Message}");
                    }
                    lblStatus.Text = $"爬取完成，找到 {_phoneNumbers.Count} 个电话号码";
                    lblStatus.Refresh();
                }));
            }
            catch (Exception ex)
            {
                Log($"搜索时出错: {ex.Message}");
            }
        }

        private IEnumerable<string> ExtractUrlsFromSearchResults(string html)
        {
            // Bing 搜索结果解析
            var pattern = @"<a\s+[^>]*href\s*=\s*[""']([^""']*)[""'][^>]*>";
            return Regex.Matches(html, pattern)
                       .Cast<Match>()
                       .Select(m => m.Groups[1].Value)
                       .Where(url => !url.Contains("bing.com") &&
                              !url.StartsWith("javascript") &&
                              Uri.IsWellFormedUriString(url, UriKind.Absolute))
                       .Distinct();
        }

        

        private async Task ProcessUrl(string url)
        {
            if (_visitedUrls.Contains(url) || _phoneNumbers.Count >= _targetCount)
                return;

            _visitedUrls.Add(url);
            UpdateUrlList(url);

            try
            {
                var response = await _httpClient.GetAsync(url);
                if (response.IsSuccessStatusCode)
                {
                    string html = await response.Content.ReadAsStringAsync();
                    ExtractPhoneNumbers(html, url);
                }
                else
                {
                    Log($"获取 {url} 内容时出错，状态码: {response.StatusCode}");
                }
            }
            catch (Exception ex)
            {
                Log($"获取 {url} 内容时出错: {ex.Message}");
            }
        }

        private void ExtractPhoneNumbers(string html, string url)
        {
            // 改进后的电话匹配
            string pattern = @"(?:电话|Tel|联系电话?)[：:\s]*([0-9\-\(\)\s]{7,15})";
            var matches = Regex.Matches(html, pattern);

            foreach (Match match in matches)
            {
                string rawPhone = match.Groups[1].Value;
                string phone = CleanPhoneNumber(rawPhone);

                if (!string.IsNullOrEmpty(phone))
                {
                    _phoneNumbers.AddOrUpdate(phone,
                        new HashSet<string> { url },
                        (key, set) => { set.Add(url); return set; });

                    UpdateResultsList(phone, url);
                }
            }
        }

        private string CleanPhoneNumber(string phone)
        {
            // 清理电话号码中的非数字字符（保留区号和分机）
            return Regex.Replace(phone, @"[^\d-]", "").Trim();
        }

        private bool IsValidPhoneNumber(string phone)
        {
            // 验证电话号码格式
            return Regex.IsMatch(phone, @"^(0\d{2,3}-\d{7,8}|1[3-9]\d{9})$");
        }

        private void UpdateResultsList(string phone, string url)
        {
            if (lstResults.InvokeRequired)
            {
                lstResults.Invoke(new Action(() => UpdateResultsList(phone, url)));
                return;
            }

            var item = new ListViewItem(phone);
            item.SubItems.Add(url);
            lstResults.Items.Add(item);
            lstResults.TopItem = item;
        }

        private void UpdateUrlList(string url)
        {
            if (lstUrls.InvokeRequired)
            {
                lstUrls.Invoke(new Action(() => UpdateUrlList(url)));
                return;
            }

            lstUrls.Items.Add(url);
            lstUrls.TopItem = lstUrls.Items[lstUrls.Items.Count - 1];
        }

        private void Log(string message)
        {
            if (txtLog.InvokeRequired)
            {
                txtLog.Invoke(new Action(() => Log(message)));
                return;
            }

            txtLog.AppendText($"{DateTime.Now:HH:mm:ss} - {message}{Environment.NewLine}");
        }

        private void lstUrls_Click(object sender, EventArgs e)
        {

        }

        private void lstUrls_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}